package com.webware.one.server.service;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.webware.one.client.GwtRpcService;
import com.webware.one.server.dao.UserDao;
import com.webware.one.server.domain.User;
import com.webware.one.shared.Constants;
import com.webware.one.shared.dto.UserDto;
import com.webware.one.shared.exception.AnyServiceException;

@Transactional
@Service
public class GwtRpcServiceImpl implements GwtRpcService {

    public final Logger log = Logger.getLogger(GwtRpcServiceImpl.class
	    .getName());

    @Autowired
    ApplicationContext ctx;

    @Autowired
    UserDao userDao;

    @PersistenceContext
    protected EntityManager em;

    public UserDto getCurrentUser() throws AnyServiceException {
	Authentication token = SecurityContextHolder.getContext()
		.getAuthentication();
	if (token != null && token.getPrincipal() != null
		&& token.getPrincipal() instanceof UserDetails) {
	    UserDetails principal = (UserDetails) token.getPrincipal();
	    for (GrantedAuthority authority : principal.getAuthorities()) {
		if (authority.getAuthority().equalsIgnoreCase(
			Constants.ROLE_ADMIN))
		    return new UserDto(null, principal.getUsername(),
			    "Администратор", "Администратор", "", null, true,
			    false, false);
	    }
	    // User user = userDao.findByLogin(principal.getUsername());
	    // if (userImpl != null)
	    // return userImpl.toDto();
	}
	return null;
    }

    @Deprecated
    public void logout() throws AnyServiceException {
	SecurityContextHolder.clearContext();
    }

    /**
     * Изменять описание/пароль могут все
     */
    @Secured({ Constants.ROLE_ADMIN, Constants.ROLE_USER,
	    Constants.ROLE_OPERATOR })
    public Long saveUser(UserDto user, String password)
	    throws AnyServiceException {
	User entity = userDao.save(user, password);
	return entity.getId();
    }

    /**
     * Изменять описание/пароль могут все
     */
    @Secured({ Constants.ROLE_ADMIN, Constants.ROLE_USER,
	    Constants.ROLE_OPERATOR })
    public Long saveUser(UserDto user) throws AnyServiceException {
	User entity = userDao.save(user);
	return entity.getId();
    }

    @Secured({ Constants.ROLE_ADMIN })
    public void deleteUser(Long userId) throws AnyServiceException {
	userDao.remove(userDao.findById(userId));
    }

    public void test() throws AnyServiceException {
	// если не пусто выходим
	Query qq = em.createQuery("SELECT u FROM User u");
	List<?> list = qq.getResultList();
	if (!list.isEmpty()) return;

	String OPERATOR_EMAIL = "petrov@qqq.ru";
	UserDto userOperator = new UserDto(null, "operator",
		"Фамилия Имя Отчество", "Оператор", OPERATOR_EMAIL, null,
		false, false, false);
	userOperator.setId(saveUser(userOperator, "12345678"));

	UserDto u = new UserDto(
		null,
		"user",
		"Сараев Дмитрий Владимирович",
		"Заместитель начальника Правового управления Правительства Москвы",
		null, null, false, false, false);
	u.setId(saveUser(u, "user"));

	List<UserDto> users = new ArrayList<UserDto>();
	users.add(u);

    }
}
